﻿// -----------------------------------------------------------------------
// <copyright file="Normalize.cs" company="FCIS">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace LastVersionOfIpPackage.Operations
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using LastVersionOfIpPackage.Enum_needed;

    /// <summary>
    /// normalize make.
    /// </summary>
    public class Normalize
    {
        /// <summary>
        /// static object of this class to use this without create object
        /// </summary>
        private static Normalize normalize = new Normalize();

        /// <summary>
        /// Gets or sets the normalize11.
        /// </summary>
        /// <value>
        /// The normalize11.
        /// </value>
        public static Normalize Normalize11
        {
            get { return Normalize.normalize; }
            set { Normalize.normalize = value; }
        }

        /// <summary>
        /// Normalizations the buffer.
        /// </summary>
        /// <param name="redBuffer">The red buffer of red color for each pixels.</param>
        /// <param name="greenBuffer">The buffer of green color for each pixels.</param>
        /// <param name="blueBuffer">The buffer of blue color for each pixels.</param>
        /// <returns>
        /// color of new image
        /// </returns>
       public Color[,] Normalization(double[,] redBuffer, double[,] greenBuffer, double[,] blueBuffer)
        {
           try
           {
               double[,,] buffer = new double[blueBuffer.GetLength(0), blueBuffer.GetLength(1), 3];
               for (int i = 0; i < blueBuffer.GetLength(1); i++)
               {
                   for (int j = 0; j < blueBuffer.GetLength(0); j++)
                   {
                       buffer[j, i, 0] = redBuffer[j, i];
                       buffer[j, i, 1] = greenBuffer[j, i];
                       buffer[j, i, 2] = blueBuffer[j, i];
                   }
               }

               return this.Normalization(buffer);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }

       /// <summary>
       /// Normalizations the buffer.
       /// </summary>
       /// <param name="valueWouldNormalizeIt">The value would normalize it.</param>
       /// <returns>
       /// color of new image
       /// </returns>
       public Color[,] Normalization(double[,,] valueWouldNormalizeIt)
       {
           try
           {
               int[,] redNormalize = this.Normalization(ColorNeed.Red, valueWouldNormalizeIt);
               int[,] greenNormalize = this.Normalization(ColorNeed.Green, valueWouldNormalizeIt);
               int[,] blueNormalize = this.Normalization(ColorNeed.Blue, valueWouldNormalizeIt);
               return BufferOfImage.Buffer.GetBuffer(redNormalize, greenNormalize, blueNormalize);
           }
           catch
           {
               throw;
           }
       }

        /// <summary>
        /// Normalizations the specified color.
        /// </summary>
        /// <param name="color">The color need normalize it.</param>
        /// <param name="valueWouldNormalizeIt">The value would normalize it.</param>
        /// <returns>
        /// color of new image
        /// </returns>
        public Color[,] Normalization(ColorNeed color, double[,] valueWouldNormalizeIt)
        {
            try
            {
                int[,] valueAfterNormalize = new int[valueWouldNormalizeIt.GetLength(0), valueWouldNormalizeIt.GetLength(1)];
                valueAfterNormalize = this.Normalization1(color, valueWouldNormalizeIt);
                double[] values = new double[3];
                int index = 0;
                switch (color)
                {
                    case ColorNeed.Red:
                        {
                            values[1] = 0;
                            values[2] = 0;
                            index = 0;
                        }

                        break;
                    case ColorNeed.Green:
                        {
                            values[0] = 0;
                            values[2] = 0;
                            index = 1;
                        }

                        break;
                    case ColorNeed.Blue:
                        {
                            values[1] = 0;
                            values[0] = 0;
                            index = 2;
                        }

                        break;
                }

                Color[,] newBufferOfImage = new Color[valueWouldNormalizeIt.GetLength(0), valueWouldNormalizeIt.GetLength(1)];
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[index] = (double)valueAfterNormalize[j, i];
                            newBufferOfImage[j, i] = Color.FromArgb((int)values[0], (int)values[1], (int)values[2]);
                        }
                    }

                    return newBufferOfImage;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }

        /// <summary>
        /// Normalizations the specified color.
        /// </summary>
        /// <param name="color">The color need normalize it.</param>
        /// <param name="valueWouldNormalizeIt">The value of buffer of image.</param>
        /// <returns>buffer of specified color</returns>
        public int[,] Normalization(ColorNeed color, double[,,] valueWouldNormalizeIt)
        {
            double max = -1, min = 256;
            int index = 0;
            switch (color)
            {
                case ColorNeed.Red:
                    {
                        index = 0;
                    }

                    break;
                case ColorNeed.Green:
                    {
                        index = 1;
                    }

                    break;
                case ColorNeed.Blue:
                    {
                        index = 2;
                    }

                    break;
            }

            try
            {
                for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                {
                    for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                    {
                        if (valueWouldNormalizeIt[j, i, index] > max)
                        {
                            max = valueWouldNormalizeIt[j, i, index];
                        }

                        if (valueWouldNormalizeIt[j, i, index] < min)
                        {
                            min = valueWouldNormalizeIt[j, i, index];
                        }
                    }
                }

                int[,] values = new int[valueWouldNormalizeIt.GetLength(0), valueWouldNormalizeIt.GetLength(1)];
                if (min != max && !(min > 0 && min < 255 && max > 0 && max < 255))
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = (int)(((valueWouldNormalizeIt[j, i, index] - min) / (max - min)) * 255);
                        }
                    }
                }
                else if (min > 0 && min < 255 && max > 0 && max < 255)
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = (int)valueWouldNormalizeIt[j, i, index];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = 0;
                        }
                    }
                }

                return values;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }

        /// <summary>
        /// Normalization1s the specified color.
        /// </summary>
        /// <param name="color">The color would normalize it.</param>
        /// <param name="valueWouldNormalizeIt">The value would normalize it.</param>
        /// <returns>buffer of specified color after normalize</returns>
        public int[,] Normalization1(ColorNeed color, double[,] valueWouldNormalizeIt)
        {
            double max = -1, min = 256;
            try
            {
                for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                {
                    for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                    {
                        if (valueWouldNormalizeIt[j, i] > max)
                        {
                            max = valueWouldNormalizeIt[j, i];
                        }

                        if (valueWouldNormalizeIt[j, i] < min)
                        {
                            min = valueWouldNormalizeIt[j, i];
                        }
                    }
                }

                int[,] values = new int[valueWouldNormalizeIt.GetLength(0), valueWouldNormalizeIt.GetLength(1)];
                if (min != max && !(min > 0 && min < 255 && max > 0 && max < 255))
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = (int)(((valueWouldNormalizeIt[j, i] - min) / (max - min)) * 255);
                        }
                    }
                }
                else if (min > 0 && min < 255 && max > 0 && max < 255)
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = (int)valueWouldNormalizeIt[j, i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < valueWouldNormalizeIt.GetLength(1); i++)
                    {
                        for (int j = 0; j < valueWouldNormalizeIt.GetLength(0); j++)
                        {
                            values[j, i] = 0;
                        }
                    }
                }

                return values;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw ex;
            }
        }
    }
}
